Can I Change to PMode without dealing with LGDT, LIDT etc, maybe by setting FS,GS port 0x64 A20line directly ?
If you CLI and disable hardware interrupts, you "might" be able to run without LIDT. I wouldn't recommend it though.
LGDT... hrum. You do need two descriptors.
LGDT... hrum. You do need two descriptors.
can I use it to change to Protected mode? what is GS used for? it value alway NULL, and FS always 0x167 or 0x16F. BTW what LGDT do?
Switch to mode:
(or "inc eax" if you're positive you're in realmode - which you should be, if you're doing the switch ;) ).
As for all your other questions... go get yourself a copy of the intel pentium4 manuals, the "systems programming guide" is a good place to look. http://www.nondot.org/sabre/os/articles isn't a bad place to look either.
mov eax, cr0
or eax, 1
mov cr0, eax
(or "inc eax" if you're positive you're in realmode - which you should be, if you're doing the switch ;) ).
As for all your other questions... go get yourself a copy of the intel pentium4 manuals, the "systems programming guide" is a good place to look. http://www.nondot.org/sabre/os/articles isn't a bad place to look either.
Im using LMSW AX, where bit 0 at AX is 1. But it triple fault and the computer restarted. It not work. I'll see site right now.
Well, get the intel manuals as a "good background information", then read some osdev fundamentals. There's a bunch of things you need to do before "making the switch".
Thats why Im asking here, hoping someone tell me directly.
It's already been written countless times before - do invest some time in researching the subject yourself. The osdev link is a good hub to start from.
Im using LMSW AX, where bit 0 at AX is 1. But it triple fault and the computer restarted. It not work. I'll see site right now.
i think a cpu has at startup, in realmode, already a machine statusword (msw) which is not zero, i.e. some bits are already set @ bootup which are maybe nessecary - i don't know what flags are contained in the first 16bits, but some have to be set.
so, do it like:
mov eax,cr0 ;get the controlword
or al,1 ;modify it: set bit0
mov cr0, eax ;write it back with the one modified bit
whis would be then
smsw ax ;get the statusword
or ax,1 ;modify it: set bit0
lmsw ax ;load it back
Man welcome to the Triple Fault Club :)
(this actually exists)
It is very simple :D :
Hmmm well to switch to protected mode is NOT that simple check my SOLAR OS source code ...
When you setup CR0's bit 0 to 1 you must allready have done at least this:
0. Disable Interupts
--------------------------------
We do not want an int to come in the most unpleasant moment do we?
1.Enable A20 line
----------------------------
Without this you will only see memory 0-1M 2-3M 5-6M one mega holes everywhere :D
Use the keyboard controler for this. Now this controller is over used in PC's:
-it enables A20 line
-it reads keyboard
-it reads ps/2 mouse
-it can reset PC the hard way
-many other stuff...
SO take care with programming IT
2.Stetup a GDT - Global Descriptor Table with at least 3 valid descriptors:
---------------------------------------------------------------------------------------------
-first one is for free all zero because Intel wants it like this
-second one should be a code descriptor i recommend it and easy base=0...size=4G setup
-third one must be a data selector (universal data lets say) i also recomend base=0...size=4G
The data and code selectors in protected mode MUST be diferent! a code selector is NEVER writable
BTW
-selector 0 == 0000
-selector 1 == 0008
-selector 2 == 0010
aka the actual addr in GDT and selectord are all 16 bit words
3-Load this prepared GDT into CPU
------------------------------------------------
USE LGDT or older instructions. Do not jump do not breathe do not enable ints do not fault DO NOTHING!
4.Enable protected Mode
------------------------------------------
mov eax,CR0
or eax,1
mov CR0,eax
Use a directive that will tell your assembler this is 32bit code from now on
like:a segment with USE32 attribute or in NASM or .USE32 in FASM
5. LOAD all older segment registers with the new selectors
----------------------------------------------------------------------------
Load ds,es,ss,fs,gs with selector 3. theoretically ss should have a diferent selector but doh...
You can NOT load CS selector directly for obviouse reasons (it is just where you are executing program now)
SO you have to use a FAR intersegment jump see below:
6-JUMP far to setup the CS selector:
------------------------------------------------
Theoreticaly you should use hardcoded hex jump with opcode (EA) , 32bit offset of next instruction to execute... usually just a few bytes away :) and selector 02 instead of segment . This is a 48 bits pointer!
This JUMP will do the CS selector load for you
COntinue in 32bit flat memory model from now on , be happy do not worry
ZZZZ- Errors
---------------------------------------------------------------
ANY error in above esp GDT and selectors setupwill most likely triple fault. Why well because you do not have valid IDT table. Besides Hardware IRQs that you have somehow disabled via CLI in this table are also Fault handlers, so any error (first fault) will go there but it will not find a valid descriptor (seccond fault) well this will triger and invalid descriptor fault (3rd faulf) ... here CPU gives up and RESET's itself :D
Have a nice day !!!
It might help a lot to directly print caracters in text video buffer at B8000 or B800:0000 (in real mode) at each stage of above steeps... if it triple faults you might be fast eaye and see where it reached (at least i did). You cand also insert dummy infinnite loops before presumed error...if it is habging but NOT triple faulting ... then all is ok until there ....
Now this IS funny a HANGED MACHINE menas NO GPF :D
XXX.Eventually setup and IDT.
-------------------------------------
Theoretically if you did all above ok you might avoid this steep but honestly not for much longer, just until testing above ok
Of course this is a very limited and simple setup, real OSes do much more than this but doh.. it is a start
Realy do you think you have the nerves for this ?
Because this is only the start my friend
(this actually exists)
It is very simple :D :
Hmmm well to switch to protected mode is NOT that simple check my SOLAR OS source code ...
When you setup CR0's bit 0 to 1 you must allready have done at least this:
0. Disable Interupts
--------------------------------
We do not want an int to come in the most unpleasant moment do we?
1.Enable A20 line
----------------------------
Without this you will only see memory 0-1M 2-3M 5-6M one mega holes everywhere :D
Use the keyboard controler for this. Now this controller is over used in PC's:
-it enables A20 line
-it reads keyboard
-it reads ps/2 mouse
-it can reset PC the hard way
-many other stuff...
SO take care with programming IT
2.Stetup a GDT - Global Descriptor Table with at least 3 valid descriptors:
---------------------------------------------------------------------------------------------
-first one is for free all zero because Intel wants it like this
-second one should be a code descriptor i recommend it and easy base=0...size=4G setup
-third one must be a data selector (universal data lets say) i also recomend base=0...size=4G
The data and code selectors in protected mode MUST be diferent! a code selector is NEVER writable
BTW
-selector 0 == 0000
-selector 1 == 0008
-selector 2 == 0010
aka the actual addr in GDT and selectord are all 16 bit words
3-Load this prepared GDT into CPU
------------------------------------------------
USE LGDT or older instructions. Do not jump do not breathe do not enable ints do not fault DO NOTHING!
4.Enable protected Mode
------------------------------------------
mov eax,CR0
or eax,1
mov CR0,eax
Use a directive that will tell your assembler this is 32bit code from now on
like:a segment with USE32 attribute or in NASM or .USE32 in FASM
5. LOAD all older segment registers with the new selectors
----------------------------------------------------------------------------
Load ds,es,ss,fs,gs with selector 3. theoretically ss should have a diferent selector but doh...
You can NOT load CS selector directly for obviouse reasons (it is just where you are executing program now)
SO you have to use a FAR intersegment jump see below:
6-JUMP far to setup the CS selector:
------------------------------------------------
Theoreticaly you should use hardcoded hex jump with opcode (EA) , 32bit offset of next instruction to execute... usually just a few bytes away :) and selector 02 instead of segment . This is a 48 bits pointer!
This JUMP will do the CS selector load for you
COntinue in 32bit flat memory model from now on , be happy do not worry
ZZZZ- Errors
---------------------------------------------------------------
ANY error in above esp GDT and selectors setupwill most likely triple fault. Why well because you do not have valid IDT table. Besides Hardware IRQs that you have somehow disabled via CLI in this table are also Fault handlers, so any error (first fault) will go there but it will not find a valid descriptor (seccond fault) well this will triger and invalid descriptor fault (3rd faulf) ... here CPU gives up and RESET's itself :D
Have a nice day !!!
It might help a lot to directly print caracters in text video buffer at B8000 or B800:0000 (in real mode) at each stage of above steeps... if it triple faults you might be fast eaye and see where it reached (at least i did). You cand also insert dummy infinnite loops before presumed error...if it is habging but NOT triple faulting ... then all is ok until there ....
Now this IS funny a HANGED MACHINE menas NO GPF :D
XXX.Eventually setup and IDT.
-------------------------------------
Theoretically if you did all above ok you might avoid this steep but honestly not for much longer, just until testing above ok
Of course this is a very limited and simple setup, real OSes do much more than this but doh.. it is a start
Realy do you think you have the nerves for this ?
Because this is only the start my friend
0. Disable Interupts
This also means hardware/NMI - CLI is not enough!
TRUE f0dder
but i was still editing my message and saved it with a post :P
And he has a fair chance that a NMI wil not occur on his machine,
Any other thing will be just plain bad luck :D
but i was still editing my message and saved it with a post :P
And he has a fair chance that a NMI wil not occur on his machine,
Any other thing will be just plain bad luck :D
I write it this on my compiler
edit: Hope someone interested with my compiler and studied it. BTE:Bogdan, I'll support your OS after I finished my Compiler. My compiler will use diskless system,so it can run on any OS.
;By Onan Farabi
;Untuk Pindah ke PMode, blom selesai
;CS harus 8000 dan IP harus 0000
cmp al,al ; compare al with al
jz 20 ; it must be same, jump to CS:IP + 0x20(32)
db FFFF0000 ; Variable GDT DS:[5]
db 9a000000 ; VAR DS:[9]
db FFFF0000 ; VAR DS:[13]
db 92008F00 ; VAR DS:[17]
db FFFF0000 ; VAR DS:[21]
db 92000000 ; VAR Variable 24 byte long DS:[25]
db FFFFFFFF ; Null Selector DS:[29]
db FFFFFFFF ; Zero it by your self. DS:[33]
cli ; Clear Interupt DS:[37]
mov ax,cs ; move valu cs to ax
mov ds,ax ; move ax to DS
mov es,ax ; es=cs
mov ss,ax ; ss=cs
mov di,9 ; DI point to GDT
mov ax,[edi] ; move word at DI to ax
xchg al,ah ; exchabge it
mov [edi],ax ; store it again
_add di,8 ; add DI with 8
mov ax,[edi] ; now edi = 17
xchg al,ah ; same with above
mov [edi],ax ; SWA
_add di,8 ; now edi = 25
mov [edi],ax ; SDA
mov di,1b ; Null Selector address
xor eax,eax ; Reset eax
mov [edi],eax ; Null selektor value no zero
_add di,4 ; now DI arei 31
mov [edi],eax ; all Null selektor zero
lgdt [5] ; DS:[5], address LGDT. Self count
Smsw ax ; Self explain
_or al,1 ;
LMSW ax ; welcome to Pmode
prefix ; it same with use 32 on NASM change default bit
mov eax,ecx ; Lihat perbedaannya
mov ax,cx ; Check the Different
sti ; Set Interupt
ret ; ret back
edit: Hope someone interested with my compiler and studied it. BTE:Bogdan, I'll support your OS after I finished my Compiler. My compiler will use diskless system,so it can run on any OS.
Man
First of all, even if my country has a border with Turkey, and we had quite a few wars in old times, I DO NOT UNDERSTAND turkysh language... PLEASE kkep it in english on this board :D
but this comment on English is funny:
Haha, instead please read:
STI ; SET INTERUPT FLAG
there are many many more simple and clearer written examples of boot codes and switch to Pmode,
Must of been hundreds last time i have checked, some even load COFF or PE kernels, relocate them and BSS sections and start execute ... so ...
any special interest in this one i do not understand :P
:stupid:
First of all, even if my country has a border with Turkey, and we had quite a few wars in old times, I DO NOT UNDERSTAND turkysh language... PLEASE kkep it in english on this board :D
but this comment on English is funny:
STI ; store interupt
Haha, instead please read:
STI ; SET INTERUPT FLAG
there are many many more simple and clearer written examples of boot codes and switch to Pmode,
Must of been hundreds last time i have checked, some even load COFF or PE kernels, relocate them and BSS sections and start execute ... so ...
any special interest in this one i do not understand :P
:stupid:
Its Indonesia language, I have recomented it with english. I thinks the only one I dont understand is the LGDT section. My code load LGDT DS:[5] or LGDT ES:[5] etc..
well i actually understand but i DO nOT WNAT to explain an application that CHOOSES to jump 20 bytes ahed without defineing an label for this jump :(
This guy wanted to do a poor crackme :) ?
or it is dissassemble code or what?
I mean what wrong can a label do there?
This guy wanted to do a poor crackme :) ?
or it is dissassemble code or what?
I mean what wrong can a label do there?
well man
Read LGDT instruction in Intel manuals?
That :5 is again extra cryptic... what is that? the worst example on EARTH? how did you found it...?
Well LGDT needs a parameter an memory addres (pointer to)
and structure of 48 bytes containing size of GDT on 16 bits and an linear memory addres base for GDT on the 32 bits.
Because each selector descriptor has 8 bytes the 16 bit limit value sets a max of 8192 selectors available
There are so many mistakes in above code that is actually funny... it must be ...
db 0ffh,0ffh,00,00 ---- i guess for example, maybe some funny assembler i do not know yet though...
db 9ah,00,00,00
anyway depends on WHERE the code was loaded / relocated/moved
so limit is 0xFFFF =65536
and base for GDT 009A0000
Or is it the other way arround?
This guy uses a trick of storing the size /limit structure in the first selector that is RESERVED by INTEL and SHOULD be ZERO... as stated in MANUALS...
Yes i know it works...
But it is just bad habit to ignore reserved things...
Honestly i do not care :P for such baddly unclear written code :P
Pleas tell me I DID NOT wrote that code when i was sleeping and dreaming of electronic sheeps and OS programming ... please
Read LGDT instruction in Intel manuals?
That :5 is again extra cryptic... what is that? the worst example on EARTH? how did you found it...?
Well LGDT needs a parameter an memory addres (pointer to)
and structure of 48 bytes containing size of GDT on 16 bits and an linear memory addres base for GDT on the 32 bits.
Because each selector descriptor has 8 bytes the 16 bit limit value sets a max of 8192 selectors available
There are so many mistakes in above code that is actually funny... it must be ...
db 0ffh,0ffh,00,00 ---- i guess for example, maybe some funny assembler i do not know yet though...
db 9ah,00,00,00
anyway depends on WHERE the code was loaded / relocated/moved
so limit is 0xFFFF =65536
and base for GDT 009A0000
Or is it the other way arround?
This guy uses a trick of storing the size /limit structure in the first selector that is RESERVED by INTEL and SHOULD be ZERO... as stated in MANUALS...
Yes i know it works...
But it is just bad habit to ignore reserved things...
Honestly i do not care :P for such baddly unclear written code :P
Pleas tell me I DID NOT wrote that code when i was sleeping and dreaming of electronic sheeps and OS programming ... please
bogdan, iirc the intel manuals state the first entry will be ignored. Might be wrong, but I have a vague remembrance of thinking "hm, storing ptr+limit there? Seems hacky", then re-reading the PDFs and thinking "oh".
...had a look at the docs again. The intel manual clearly states: "The first descriptor in the GDT is not used by the processor."
...had a look at the docs again. The intel manual clearly states: "The first descriptor in the GDT is not used by the processor."
Well, even if Intel manuals have relaxed the issue a bit..
Really Why do it like that? why not use other 6 bytes of ram somewhere. I mean is not like a big deal waste : 6 byes? That is not and embeded system is it?
If not embeded i will expect it to have at least 1-2Megabytes of RAM ...available
So for the readers peace of mind and clear / easy understanding and for ME .... it would have been better to use a separated memory variable for this OTHER than GDT start i mean.
But doh this is only IMHO of course.
Also this DS:5 without a variable name is again funny at least...like that ASM did not supported labels...
but that " _eax " makes me suspiciouse
Really Why do it like that? why not use other 6 bytes of ram somewhere. I mean is not like a big deal waste : 6 byes? That is not and embeded system is it?
If not embeded i will expect it to have at least 1-2Megabytes of RAM ...available
So for the readers peace of mind and clear / easy understanding and for ME .... it would have been better to use a separated memory variable for this OTHER than GDT start i mean.
But doh this is only IMHO of course.
Also this DS:5 without a variable name is again funny at least...like that ASM did not supported labels...
but that " _eax " makes me suspiciouse
Even intel386.txt says "The first entry of the GDT (INDEX=0) is not used by the processor, however.", so it should be safe :).
I don't see any special reason to do it, but I don't see any reason not to do it either. I mean, intel has been documenting since 80386 that the first entry isn't used, so it's not "undocumented behaviour" that it works. *shrug*, each to his own.
You are right about the "magic number" appearance of the code - icky :)
I don't see any special reason to do it, but I don't see any reason not to do it either. I mean, intel has been documenting since 80386 that the first entry isn't used, so it's not "undocumented behaviour" that it works. *shrug*, each to his own.
You are right about the "magic number" appearance of the code - icky :)