need help go to protected mode

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
xavmoss
Posts: 14
Joined: Thu Oct 12, 2006 2:56 am

need help go to protected mode

Post by xavmoss »

I made program using masm that go to proctected mode but the program always restart the CPU. Anyone can help with this. please help me

Code: Select all

lgdt	fword ptr cs:[GDT_Ptr]	; Load GDT
mov eax,cr0	  	  	
or al,01h	  	  	; Set protected mode bit
mov cr0,eax	  	  	
db	0eah	  		
dw enter_pm
dw	8

GDT is like this
GDT_Ptr		dw	gdt_size,0,0
null_dscr	dw 	0,0,0,0,0
code32_SEL	equ	$-GDT_Ptr
code32_dscr	dw	0ffffh,0,10,9ah,0cfh,0
data32_SEL	equ	$-GDT_Ptr
data32_dscr	dw	0ffffh,0,10,92h,0cfh,0
code1632_SEL	equ	$-GDT_Ptr
code16_dscr	dw	0ffffh,0,0,9ah,0,0
data16_SEL	equ	$-GDT_Ptr
data16_dscr	dw	0ffffh,0,0,92h,0,0
video_SEL	equ	$-GDT_Ptr
videosel_dscr	dw      0ffffh,8000h,0bh,92h,0,0
TSS1 		dw 	0ffffh,0,0,89h,0cfh,0
TSS2		dw 	0ffffh,0,0,89h,0cfh,0
gdt_size=$-(offset null_dscr)


TheQuux
Member
Member
Posts: 73
Joined: Sun Oct 22, 2006 6:49 pm

Post by TheQuux »

do a "cli" first... what's going on is that your OS gets a timer interrupt, which is not handled because you don't have a pmode IDT, so your CPU triple faults, which makes the computer reboot.

Now, if you actually do want to reboot that does work...

Code: Select all

reboot:
    lidt [v00tage]
    int 1
v00tage: dd 0,0,0,0
Note: that's for nasm.
I haven't workind in masm for 4-5 years, so I'm a bit rusty...
My project: Xenon
xavmoss
Posts: 14
Joined: Thu Oct 12, 2006 2:56 am

Post by xavmoss »

I already using cli. And for IDT using this code.

Code: Select all

lidt	fword ptr cs:[IDT_PTr]	; load IDT
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Tried using a debugger, like Bochs?
"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 ]
xavmoss
Posts: 14
Joined: Thu Oct 12, 2006 2:56 am

Post by xavmoss »

I cannot assign my program to bosch. I don't understand how to run the program in bosch.
xavmoss
Posts: 14
Joined: Thu Oct 12, 2006 2:56 am

Post by xavmoss »

i change my GDT and IDT but still restart
please help me

Code: Select all

GDTDESC struc
  limit_0_15		dw	0	; low word of the segment length
  base_addr0_15		dw	0	; low word of base address
  base_addr16_23	db	0	; low byte of high word of base addr.
  access		db	0	
  limit_H		db 	0
  base_addr24_31	db	0	; highest byte of base address
GDTDESC ends

IDTDESC struc
  offset0_15	dw	?		; low word of handler offset
  selector0_15	dw	?		; segment selector
  zero_byte	db	0		; unused in this descriptor format
  access1	db	?		; flag-byte
  offset16_31	dw	?		; high word of handler offset
IDTDESC ends

GDT_Ptr		dw	gdt_size,0,0
null_dscr	dw 	0,0,0,0,0
code32_SEL	equ	$-null_dscr
code32_dscr	GDTDESC <-1,0,10,9ah,0cfh,0>
data32_SEL	equ	$-null_dscr
data32_dscr	GDTDESC <-1,0,10,92h,0cfh,0>
video_SEL	equ	$-null_dscr
videosel_dscr	GDTDESC <-1,8000h,0bh,92h,0,0>
code16_SEL	equ	$-null_dscr
code16_dscr	GDTDESC <-1,0,0,9ah,0,0>
data16_SEL	equ	$-null_dscr
data16_dscr	GDTDESC <-1,0,0,92h,0,0>
TSS1_SEL	equ	$-null_dscr
TS1 		GDTDESC <-1,0,0,89h,0cfh,0>
TSS2_SEL	equ	$-null_dscr
TS2		GDTDESC <-1,0,0,89h,0cfh,0>
gdt_size=$-(offset null_dscr)

IDT_Ptr   	dw   	idt_size,0,0
interrupt0	IDTDESC	<int0h,code32_SEL,0,8fh,0>
interrupt1	IDTDESC	<int1h,code32_SEL,0,8fh,0>
interrupt2	IDTDESC	<int2h,code32_SEL,0,8fh,0>
interrupt3	IDTDESC	<int3h,code32_SEL,0,8fh,0>
interrupt4	IDTDESC	<int4h,code32_SEL,0,8fh,0>
interrupt5	IDTDESC	<int5h,code32_SEL,0,8fh,0>
interrupt6	IDTDESC	<int6h,code32_SEL,0,8fh,0>
interrupt7	IDTDESC	<int7h,code32_SEL,0,8fh,0>
interrupt8	IDTDESC	<int8h,code32_SEL,0,8fh,0>
interrupt9	IDTDESC	<int9h,code32_SEL,0,8fh,0>
interruptA	IDTDESC	<intAh,code32_SEL,0,8fh,0>
interruptB	IDTDESC	<intBh,code32_SEL,0,8fh,0>
interruptC	IDTDESC	<intCh,code32_SEL,0,8fh,0>
interruptD	IDTDESC	<intDh,code32_SEL,0,8fh,0>
interruptE	IDTDESC	<intEh,code32_SEL,0,8fh,0>
interruptF	IDTDESC	<intFh,code32_SEL,0,8fh,0>
interrupt10	IDTDESC	<int10h,code32_SEL,0,8fh,0>
interrupt11	IDTDESC	<int11h,code32_SEL,0,8fh,0>
interrupt12	IDTDESC	<int12h,code32_SEL,0,8fh,0>
interrupt13	IDTDESC	<int13h,code32_SEL,0,8fh,0>
interrupt14	IDTDESC	<int14h,code32_SEL,0,8fh,0>
interrupt15	IDTDESC	<int15h,code32_SEL,0,8fh,0>
interrupt16	IDTDESC	<int16h,code32_SEL,0,8fh,0>
interrupt17	IDTDESC	<int17h,code32_SEL,0,8fh,0>
interrupt18	IDTDESC	<int18h,code32_SEL,0,8fh,0>
interrupt19	IDTDESC	<int19h,code32_SEL,0,8fh,0>
interrupt1A	IDTDESC	<int1Ah,code32_SEL,0,8fh,0>
interrupt1B	IDTDESC	<int1Bh,code32_SEL,0,8fh,0>
interrupt1C	IDTDESC	<int1Ch,code32_SEL,0,8fh,0>
interrupt1D	IDTDESC	<int1Dh,code32_SEL,0,8fh,0>
interrupt1E	IDTDESC	<int1Eh,code32_SEL,0,8fh,0>
interrupt1F	IDTDESC	<int1Fh,code32_SEL,0,8fh,0>
interrupt20	IDTDESC	<int20h,code32_SEL,0,8eh,0>
interrupt21	IDTDESC	<int21h,code32_SEL,0,8eh,0>
interrupt22	IDTDESC	<int22h,code32_SEL,0,8eh,0>
interrupt23	IDTDESC	<int23h,code32_SEL,0,8eh,0>
interrupt24	IDTDESC	<int24h,code32_SEL,0,8eh,0>
interrupt25	IDTDESC	<int25h,code32_SEL,0,8eh,0>
interrupt26	IDTDESC	<int26h,code32_SEL,0,8eh,0>
interrupt27	IDTDESC	<int27h,code32_SEL,0,8eh,0>
interrupt28	IDTDESC	<int28h,code32_SEL,0,8eh,0>
interrupt29	IDTDESC	<int29h,code32_SEL,0,8eh,0>
interrupt2A	IDTDESC	<int2Ah,code32_SEL,0,8eh,0>
interrupt2B	IDTDESC	<int2Bh,code32_SEL,0,8eh,0>
interrupt2C	IDTDESC	<int2Ch,code32_SEL,0,8eh,0>
interrupt2D	IDTDESC	<int2Dh,code32_SEL,0,8eh,0>
interrupt2E	IDTDESC	<int2Eh,code32_SEL,0,8eh,0>
interrupt2F	IDTDESC	<int2Fh,code32_SEL,0,8eh,0>
interrupt30	IDTDESC	<int30h,code32_SEL,0,8eh,0>
interrupt31	IDTDESC	<int31h,code32_SEL,0,8eh,0>
interrupt32	IDTDESC	<int32h,0,0,8eh,0>
idt_size=$-(offset IDT_Ptr)

call convr_addr
		cli	  	  ; Clear or disable interrupts
		lgdt	fword ptr cs:[GDT_Ptr]	; Load GDT
		lidt	fword ptr cs:[IDT_Ptr]	; load IDT
			
		;call remap_pic	
	   	mov eax,cr0	  	  	
   		or al,01h	  	  	; Set protected mode bit
	   	mov cr0,eax	  	  	
		db	0eah	  		
		dw enter_pm
		dw	8
enter_pm : 	mov ax,video_SEL
	   	mov es,ax
	   	mov ax,data32_SEL   
  	   	mov ds,ax	       
   	   	mov fs,ax
	   	mov ss,ax
	  	mov gs,ax
	   	sti

User avatar
Dex
Member
Member
Posts: 1444
Joined: Fri Jan 27, 2006 12:00 am
Contact:

Post by Dex »

Have tryed something like :
mov byte [es:0xB809E], "1"
;some code
mov byte [es:0xB809E], "2"
;some code
mov byte [es:0xB809E], "3"
;some code

In pmode or a realmode ver before pmode, also something like jmp $ just before entering pmode and if it does not crash, then try jmp $ after entering.

I would gess your jmp to pmode, is not right.
User avatar
Walling
Member
Member
Posts: 158
Joined: Mon Dec 04, 2006 6:06 am
Location: Berlin, Germany

Post by Walling »

These lines doesn't look right:

Code: Select all

...
GDT_Ptr      dw   gdt_size,0,0 
...
IDT_Ptr      dw      idt_size,0,0 
...
The "0,0" part has to be a dword containing the location of the GDT or IDT table. Example:

Code: Select all

GDT_Ptr:
  dw gdt_size
  dd GDT_Table

GDT_Table:
  ; ... descriptors ...
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Code: Select all

GDT_Ptr      dw   gdt_size,0,0 

Code: Select all

IDT_Ptr      dw      idt_size,0,0 
I sure hope you have set the offset part somewhere. I dont see that code at least.
I cannot assign my program to bosch. I don't understand how to run the program in bosch.
Tried reading the documents?
http://www.osdev.org/osfaq2/index.php/B ... 20emulator
http://bochs.sourceforge.net

[edit]same thought same time, hehe[/edit]
"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 ]
xavmoss
Posts: 14
Joined: Thu Oct 12, 2006 2:56 am

Post by xavmoss »

I using masm, so I can't using

Code: Select all

GDT_Ptr: 
  dw gdt_size 
  dd GDT_Table 

GDT_Table: 
  ; ... descriptors ...
I using this. Is it right? Thx for the links. I an amateur in thing like this. Please tell me how to set the offset if I wrong

Code: Select all


IDT 	dw 0ffh
IDT_Adr	dw 0
GDT	dw 17h
GDT_Adr	dw 0
User avatar
Walling
Member
Member
Posts: 158
Joined: Mon Dec 04, 2006 6:06 am
Location: Berlin, Germany

Post by Walling »

xavmoss wrote:I using this. Is it right? Thx for the links. I an amateur in thing like this. Please tell me how to set the offset if I wrong

Code: Select all


IDT 	dw 0ffh
IDT_Adr	dw 0
GDT	dw 17h
GDT_Adr	dw 0
I don't think it's right yet. Look.. you have an instruction LGDT. It needs the location of a structure of this format:

Code: Select all

2 bytes: Size - 1
4 bytes: Location of GDT table
The 'dw' is only a 2 byte value. So maybe you could do something like this (but I don't know MASM syntax):

Code: Select all

GDT_Ptr      dw    gdt_size
GDT_Addr     dd    GDT_Table

GDT_Table    equ   $
null_dscr    dw    0,0,0,0,0
code32_SEL   equ   $-GDT_Table
code32_dscr  GDTDESC <-1,0,10,9ah,0cfh,0>
data32_SEL   equ   $-GDT_Table
data32_dscr  GDTDESC <-1,0,10,92h,0cfh,0>
...
xavmoss
Posts: 14
Joined: Thu Oct 12, 2006 2:56 am

Post by xavmoss »

I have tried it but it still restart. I confused. I think my GDT is doesn't right. Can anyone give sample syntax GDT for masm
User avatar
smiddy
Member
Member
Posts: 127
Joined: Sun Oct 24, 2004 11:00 pm
Location: In my cube, like a good leming. ;-)

Post by smiddy »

Here's part of my GDT (which came from many sources):

Code: Select all

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;
;; Global Descriptor Table:
;;
;;           MSB    bit 6   bit 5   bit 4   bit 3   bit 2   bit 1   LSB
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;byte 0  | bit 7<---------------- segment limit------------------->bit 0 |
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;byte 1  |bit 15<---------------- segment limit------------------->bit 8 |
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;byte 2  | bit 7<---------------- segment base-------------------->bit 0 |
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;byte 3  |bit 15<---------------- segment base-------------------->bit 8 |
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;byte 4  |bit 23<---------------- segment base-------------------->bit 16|
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;byte 5  |   P   |      DPL      | <----------- segment type ----------> |
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;
;; P is the Segment Present bit. It should always be 1.
;;
;; DPL is the DESCRIPTOR PRIVILEGE LEVEL. For simple code like this, these
;; two bits should always be zeroes.
;;
;; Segment Type (again, for simple code like this) is hex 12 for data
;; segments, hex 1A for code segments.
;;
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;byte 6  |   G   |   B   |   0   | avail | bit 19<-- seg limit--->bit 16 |
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;
;; G is the Limit Granularity. If zero, the segment limit is in bytes
;; (0 to 1M, in 1-byte increments). If one, the segment limit is in 4K PAGES
;; (0 to 4G, in 4K increments). For simple code, set this bit to 1, and
;; set the segment limit to its highest value (FFFFF hex). You now have
;; segments that are 4G in size! The Intel 32-bit CPUs can address no more than
;; 4G of memory, so this is like having no segments at all.
;;
;; B is the Big bit; also called the D (Default) bit. For code segments,
;; all instructions will use 32-bit operands and addresses by default.
;;
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;byte 7  |bit 31<---------------- segment base------------------->bit 24 |
;;        +-------+-------+-------+-------+-------+-------+-------+-------+
;;
;; Build a simple GDT with four descriptors: NULL (all zeroes), linear data
;; (lets you use 32-bit addresses), code, and data/stack. (An extra
;; descriptor or two is needed to return to real mode.) For simplicity,
;; the limits of all descriptors (except NULL and the real-mode descriptors)
;; are FFFFF hex, the largest possible limit.
;;
;; NOTE: Each descriptor table can contain 8192 descriptors, so a total of
;; 16,384 descriptors in all can be avaliable to an application.
;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;


GDT:

; Index = 0h
    dd 0                ; NULL Descriptor
    dd 0                ; NULL Descriptor

; Index = 8h
GDT_DATA_LINEAR_SELECTOR:

    dw 0FFFFh           ; (8h) linear Data segment, read/write, expand down
    dw 0
    db 0
    db 10010010b
    db 11001111b
    db 0
;Index = 10h
GDT_CODE_SELECTOR:

    dw 0FFFFh           ; limit00 to limit15=0xFFFFF=4GigaByte
    dw 00000h           ; base00 to base15=0x0000
    dw 09A00h           ; 0x9=1001=P/DPL/S  0xA=1010=Type=code/nonconforming/read
    dw 000CFh           ; granularity=4096, 386 (+5th nibble of limit)

; Index = 18h
GDT_PMODE_DATA_SELECTOR:

    dw 0FFFFh           ; 4Gb - (0x100000*0x1000 = 4Gb)
    dw 00000h           ; base address=0
    dw 09200h           ; data read/write
    dw 000CFh           ; granularity=4096, 386 (+5th nibble of limit)


; Index = 20h
GDT_UNREAL_DATA_SELECTOR:       ; For use in Unreal mode

    dw 0FFFFh           ; Base - Limit: 0 - 0FFFFF * 4KB = 4GB
    dw 00000h           ; Base = 0
    dw 09200h           ; data read/write
    dw 0008Fh           ; G=1=4096 granularity, B=0, 16-bit instructions

; Index = 28h
GDT_REAL_CODE_SELECTOR:

    dw 0FFFFh           ; Segment limit is 64 kB
    dw 00000h           ; Base = 0      (fixup required in case we're over 64kB)
    dw 09A00h           ; code read
    dw 00000h           ; byte granularity, 16-bit instructions

; Index = 30h
GDT_REAL_DATA_SELECTOR:

    dw 0FFFFh           ; Segment limit is 64 kB
    dw 00000h           ; Base = 0      (fixup required in case we're over 64kB)
    dw 09200h           ; data read/write
    dw 00000h           ; byte granularity, 16-bit instructions

; Index = 38h
GDT_PnP_DATA_SELECTOR:

    dw 0FFFFh           ; Segment limit is 64 kB
    dw 0F000h           ; Base = 0 (gets updated on the fly)
    dw 0920Fh           ; data read/write : byte 5 -> base = 0 (gets updated on the fly)
    dw 00000h           ; byte granularity, 16-bit instructions (compatibility with 286 descriptor)

; Index = 40h
GDT_PnP_CODE_SELECTOR:

    dw 0FFFFh           ; Segment limit is 64 kB
    dw 00000h           ; Base = See byte 5
    dw 09A0Fh           ; code read     : byte 5 -> base = 0F0000h
    dw 00000h           ; byte granularity, 16-bit instructions

; Index = 48h
GDT_PnP_STACK_SELECTOR:

    dw 0FFFFh           ; Segment limit is 64 kB
    dw 00000h           ; Base = See byte 5, 80000h - 8FFFFh for now. May put it up higher
    dw 09208h           ; data read/write : byte 5 -> base = 80000h
    dw 00000h           ; byte granularity, 16-bit (compatible with 286 descriptors)

;Index = 50h
GDT_LINEAR_CODE_SELECTOR:

    dw 0FFFFh           ; limit00 to limit15=0xFFFFF=4GigaByte
    dw 00000h           ; base00 to base15=0x0000
    dw 09A00h           ; 0x9=1001=P/DPL/S  0xA=1010=Type=code/nonconforming/read
    dw 000CFh           ; granularity=4096, 386 (+5th nibble of limit)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; The end of the GDT - can be a lot larger...need to add TSS
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

GDTEnd:
I hope this helps!

[ edit ]
Oh poop, I forgot, you'll need this part too:

Code: Select all

    mov ax,cs                               ; Else, save CS into AX, prepare for PMode
    mov [RealModeCS],ax                     ; Save CS in RealModeCS
    movzx ebx,ax                            ; Place segment into EBX
    shl ebx,4                               ; Multiply by 16, now EBX is linear
    mov [BaseAddress],ebx                   ; Save linear BaseAddress
    mov ecx,ebx
    mov eax,ecx                             ; Put EBX in EAX for manipulation
    mov [GDT_CODE_SELECTOR + 2],ax          ; Update base address
    mov [GDT_PMODE_DATA_SELECTOR + 2],ax    ; Update base address
    mov [GDT_REAL_CODE_SELECTOR + 2],ax     ; Update base address
    mov [GDT_REAL_DATA_SELECTOR + 2],ax     ; Update base address
    shr eax,16                              ; Bring upper 16-bits down to lower 16-bits
    mov [GDT_CODE_SELECTOR + 4],al          ; Update base address
    mov [GDT_PMODE_DATA_SELECTOR + 4],al    ; Update base address
    mov [GDT_REAL_CODE_SELECTOR + 4],al     ; Update base address
    mov [GDT_REAL_DATA_SELECTOR + 4],al     ; Update base address
    mov [GDT_CODE_SELECTOR + 7],ah          ; Update base address
    mov [GDT_PMODE_DATA_SELECTOR + 7],ah    ; Update base address
    mov [GDT_REAL_CODE_SELECTOR + 7],ah     ; Update base address
    mov [GDT_REAL_DATA_SELECTOR + 7],ah     ; Update base address
    add ebx,GDT                             ; Get the offset of GDT and add it to EBX (BaseAddress)
    mov [GDTR + 2],ebx                      ; Update GDTR

    lgdt [GDTR]                             ; Load GDTR
[ /EDIT ]
xavmoss
Posts: 14
Joined: Thu Oct 12, 2006 2:56 am

Post by xavmoss »

Thanks, I found that I am worng in syntax GDT for MASM. I still try to get the right syntax. And I need help to set IDT to the base address. CAn anyone give me sugestion
User avatar
Walling
Member
Member
Posts: 158
Joined: Mon Dec 04, 2006 6:06 am
Location: Berlin, Germany

Post by Walling »

Maybe these wiki pages will help you to understand the structure better: GDT, GDT for dummies and IDT. The Interrupts for dummies page is not moved to the new wiki yet, but you can find it at OsFaq2: Interrupts for dummies.

They're all worth reading. And also look at the external references.
Post Reply