hi, this is my code, for some reason it will display the "I" in real mode, pause, but then reboot without displaying the "H" i dont know why anyone know what may be up with it or what i forgot? this is my first time trying to switch to pmode... (oh by the way i use NASM)
jmp begin
bits 16
gdtr:
dw gdt_end-gdt-1
dd gdt
gdt:
gdt0: ;Null Descriptor (0)
dd 0
dd 0
gdtCode: ;Code Descriptor (1) 4GB
dw 0ffffh
dw 0
db 0
db 10011010b ;present, dpl 0, non-system, type code/execute/read (0Ah)
db 11001111b ;g=1, d/b=1
db 0
gdtData: ;Data Descriptor (2) 4GB
dw 0ffffh
dw 0
db 0
db 10010010b ;present, dpl 0, non-system, type data/read/write (02h)
db 11001111b ;g=1, d/b=1
db 0
gdtVideo: ;Video Memory Descriptor (3) 64k
dw 0ffffh
dw 08000h
db 0Bh
db 10010010b
db 00000000b
db 0
gdt_end:
; --------------------------------------------
; Here is the entry point
; --------------------------------------------
begin:
mov ax, cs ; Get the current segment
mov ds, ax ; The data is in this segment
cli ; disable interrupts while changing stack
mov ss, ax ; We'll use this segment for the stack too
mov sp, 0xfffe ; Start the stack at the top of the segment
sti ; Reenable interrupts
mov ax, 0xb800
mov es, ax
mov ax, 0x0749 ;white "I"
mov [es:0], ax
xor ah, ah
int 0x16 ;pause for key
cli
lgdt [gdtr]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp 1*8:pmresume
bits 32
pmresume:
; mov ax, 2*8 ;data segment
; mov ds, ax
mov ax, 3*8 ;video segment
mov es, ax
mov word [es:0], 0x0748 ;white "H"
jmp $
switching to pmode problem...
-
jamethiel
RE:switching to pmode problem...
The first thing that comes to mind is that unless this code is loaded at 0000:0000, the jump to pmresume is going to come out at the wrong place.
If this is a .COM file, add code to patch the GDT to the current segment (you may need to use the other granularity setting on that descriptor).
If this is a bootsector, set your assembly origin to the correct location.
If this is a .COM file, add code to patch the GDT to the current segment (you may need to use the other granularity setting on that descriptor).
If this is a bootsector, set your assembly origin to the correct location.
-
osnewbie
RE:switching to pmode problem...
here is what i tried, it still reboots. the code is compiled to a .bin file on a floppy which boot12.asm loads to 1000:0000, which is 0x10000 physical address isn't it?? i am not very good with memory addresses yet, but since i thought that that was what it was, i added the +0x10000 to the pmode offsets just for testing purposes, but it still reboots... i dont know if it is in the gdt, or if i have memory addresses wrong or what, once again, i am new to this...
any ideas appreciated!!
--------------------------
org 0x0
jmp begin
bits 16
gdtr:
dw gdt_end-gdt-1
dd gdt
gdt:
gdt0: ;Null Descriptor (0)
dd 0
dd 0
gdtCode: ;Code Descriptor (1) 4GB
dw 0ffffh
dw 0
db 0
db 10011010b ;present, dpl 0, non-system, type code/execute/read (0Ah)
db 11001111b ;g=1, d/b=1
db 0
gdtData: ;Data Descriptor (2) 4GB
dw 0ffffh
dw 0
db 0
db 10010010b ;present, dpl 0, non-system, type data/read/write (02h)
db 11001111b ;g=1, d/b=1
db 0
gdtVideo: ;Video Memory Descriptor (3) 64k
dw 0ffffh
dw 08000h
db 0Bh
db 10010010b
db 00000000b
db 0
gdt_end:
; --------------------------------------------
; Here is the entry point
; --------------------------------------------
begin:
mov ax, cs ; Get the current segment
mov ds, ax ; The data is in this segment
cli ; disable interrupts while changing stack
mov ss, ax ; We'll use this segment for the stack too
mov sp, 0xfffe ; Start the stack at the top of the segment
sti ; Reenable interrupts
mov ax, 0xb800
mov es, ax
mov ax, 0x0748
mov [es:0], ax
xor ah, ah
int 0x16
cli
lgdt [gdtr]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp dword 1*8:(pmresume+0x10000)
bits 32
pmresume:
mov ax, 2*8 ;data segment
mov ds, ax
mov gs, ax
mov fs, ax
mov ss, ax
mov sp, 0x9000
mov bp, sp
mov ax, 3*8 ;video segment
mov es, ax
mov word [es:2], 0x0749
halt:
jmp (halt+0x10000)
any ideas appreciated!!
--------------------------
org 0x0
jmp begin
bits 16
gdtr:
dw gdt_end-gdt-1
dd gdt
gdt:
gdt0: ;Null Descriptor (0)
dd 0
dd 0
gdtCode: ;Code Descriptor (1) 4GB
dw 0ffffh
dw 0
db 0
db 10011010b ;present, dpl 0, non-system, type code/execute/read (0Ah)
db 11001111b ;g=1, d/b=1
db 0
gdtData: ;Data Descriptor (2) 4GB
dw 0ffffh
dw 0
db 0
db 10010010b ;present, dpl 0, non-system, type data/read/write (02h)
db 11001111b ;g=1, d/b=1
db 0
gdtVideo: ;Video Memory Descriptor (3) 64k
dw 0ffffh
dw 08000h
db 0Bh
db 10010010b
db 00000000b
db 0
gdt_end:
; --------------------------------------------
; Here is the entry point
; --------------------------------------------
begin:
mov ax, cs ; Get the current segment
mov ds, ax ; The data is in this segment
cli ; disable interrupts while changing stack
mov ss, ax ; We'll use this segment for the stack too
mov sp, 0xfffe ; Start the stack at the top of the segment
sti ; Reenable interrupts
mov ax, 0xb800
mov es, ax
mov ax, 0x0748
mov [es:0], ax
xor ah, ah
int 0x16
cli
lgdt [gdtr]
mov eax, cr0
or eax, 1
mov cr0, eax
jmp dword 1*8:(pmresume+0x10000)
bits 32
pmresume:
mov ax, 2*8 ;data segment
mov ds, ax
mov gs, ax
mov fs, ax
mov ss, ax
mov sp, 0x9000
mov bp, sp
mov ax, 3*8 ;video segment
mov es, ax
mov word [es:2], 0x0749
halt:
jmp (halt+0x10000)
-
osnewbie
one more thing...
i also think i read somewhere about having to "code the far jump by hand" to enter pmode or something? is my jump to pmresume coded correctly and is it a far jump, or do i have to explicitly say its a far jump? if so how? and what is the difference anyway???
thanks
thanks
-
Khumba
RE:switching to pmode problem...
I am __horrible__ at pmode, but try this. I had this problem when I first tried pmode. The pointer to the GDT (gdtr) is not relative, so you might need to change "dd gdt" to "dd gdt+BASEADDRESS".
-
max
RE:switching to pmode problem...
hi -
I wrote an OS not too long ago. You have a well-known symptom here: your machine reboots because your selectors are not well set OR because your didn't make the proper jmp statement. Anyway. it all leads to triple faulting the CPU = reboot with no warnings, no error message.
I don't have time to explain how to switch to protected mode. All I can tell you is that you need to look at this code : http://www.osdev.org/developers/guide01/loader.asm
it's a kernel loader written in NASM - BTW from this website (maybe you should have looked around before asking....)
it's very well written and pretty self explanatory.
pmode is easy once you understand which address represents what. if your PC-memory addressing ability is weak, then you definitely need to pratice asm before even thinking about pmode. sorry
max
I wrote an OS not too long ago. You have a well-known symptom here: your machine reboots because your selectors are not well set OR because your didn't make the proper jmp statement. Anyway. it all leads to triple faulting the CPU = reboot with no warnings, no error message.
I don't have time to explain how to switch to protected mode. All I can tell you is that you need to look at this code : http://www.osdev.org/developers/guide01/loader.asm
it's a kernel loader written in NASM - BTW from this website (maybe you should have looked around before asking....)
it's very well written and pretty self explanatory.
pmode is easy once you understand which address represents what. if your PC-memory addressing ability is weak, then you definitely need to pratice asm before even thinking about pmode. sorry
max
-
Osnewbie
RE:switching to pmode problem...
The thing is that i did look around before posting, in fact i downloaded 3 different nasm examples, compiled them, and each one rebooted my computer. one thing i did notice is that in the list files from nasm the org xxx did not change anything. i did a little test:
org 0x0
dd 0xffffffff
here:
dd 0x88888888
dd here
and in the list it came up with 00000004 for 'here'
when i changed the org to org 0x7c00, the list file was exactly the same. so does dd here just store the relative address from the beginning of the program? and if so what good is org? either way, i tried adding the base address to the dd gdt line and it still kept rebooting...
i have also tried changing the jmp 1*8:pmresume to jmp 1*8:pmresume+BASEADDRESS and jmp dword 1*8:pmresume+BASEADDRESS which still rebooted...
org 0x0
dd 0xffffffff
here:
dd 0x88888888
dd here
and in the list it came up with 00000004 for 'here'
when i changed the org to org 0x7c00, the list file was exactly the same. so does dd here just store the relative address from the beginning of the program? and if so what good is org? either way, i tried adding the base address to the dd gdt line and it still kept rebooting...
i have also tried changing the jmp 1*8:pmresume to jmp 1*8:pmresume+BASEADDRESS and jmp dword 1*8:pmresume+BASEADDRESS which still rebooted...
-
pepito
RE:switching to pmode problem...
I belive that you can not access the GDT because the GDT BASE must be an
absolute address:
gdtr:
dw gdt_end-gdt-1
dd gdt ; <-- This is an offset, not absolute address!
In addition you are jumping out of your own program because your Code Descriptor have a BASE=0 but your program is not there (0000:0000). Then you never find the lines:
mov ax, 3*8 ;video segment
mov es, ax
mov word [es:0], 0x0748 ;white "H"
Try this (after you write the "I" char):
; Get the absolute address of your program (where you like to jump)
xor ebx, ebx
mov bx, ds ; Try too: mov bx, cs
shl ebx, 4
mov eax, ebx
; Update the BASE of the Code Descriptor and Data Descriptor
mov [gdtCode + 2], ax
mov [gdtData + 2], ax
shr eax, 16
mov [gdtCode + 4], al
mov [gdtData + 4], al
mov [gdtCode + 7], ah
mov [gdtData + 7], ah
; Update the address of the GDT
lea eax, [gdt + ebx]
mov [gdtr + 2], eax
; Switch to protected mode
cli
lgdt [gdtr] ; Load the GDT register
mov eax, cr0
or eax, 1
mov cr0, eax ; Active protected mode
jmp 1*8:pmresume ; Now you are really jump to the pmresume: label
I am new with protected mode too and this code is not mine, I get it from a Cristopher Giese demo at http://www.execpc.com/~geezer/os (now idle).
absolute address:
gdtr:
dw gdt_end-gdt-1
dd gdt ; <-- This is an offset, not absolute address!
In addition you are jumping out of your own program because your Code Descriptor have a BASE=0 but your program is not there (0000:0000). Then you never find the lines:
mov ax, 3*8 ;video segment
mov es, ax
mov word [es:0], 0x0748 ;white "H"
Try this (after you write the "I" char):
; Get the absolute address of your program (where you like to jump)
xor ebx, ebx
mov bx, ds ; Try too: mov bx, cs
shl ebx, 4
mov eax, ebx
; Update the BASE of the Code Descriptor and Data Descriptor
mov [gdtCode + 2], ax
mov [gdtData + 2], ax
shr eax, 16
mov [gdtCode + 4], al
mov [gdtData + 4], al
mov [gdtCode + 7], ah
mov [gdtData + 7], ah
; Update the address of the GDT
lea eax, [gdt + ebx]
mov [gdtr + 2], eax
; Switch to protected mode
cli
lgdt [gdtr] ; Load the GDT register
mov eax, cr0
or eax, 1
mov cr0, eax ; Active protected mode
jmp 1*8:pmresume ; Now you are really jump to the pmresume: label
I am new with protected mode too and this code is not mine, I get it from a Cristopher Giese demo at http://www.execpc.com/~geezer/os (now idle).